package holdem.pokergui;

import holdem.Card;
import holdem.network.Client;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.text.NumberFormat;
import java.util.Iterator;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;
import static javax.swing.JOptionPane.*;

/**
 *
 * @author Anders
 */

public class PokerGUI extends JFrame implements MessageReceiverInGUI
{
    static Client client;
    Player[] tabel = new Player[8];
    CardDeck deck = new CardDeck();
    boolean playing = false;
    JTextArea txtLog;
    JPanel pnlCenterCard;
    int me, turn;
    JFormattedTextField txtBet;


    void addPlayer(int place)
    {
        if (tabel[place] != null)
            return;
        else
        {
            tabel[place] = new Player();
        }
    }

    PokerGUI() throws IOException
    {
        super("Poker GUI");

        for (int i = 0; i < tabel.length; i++)
               addPlayer(i);

        //deck.cardToPlayers(tabel);

        //System.out.println(tabel[0].getHand()[0].picSource());

        setLayout(new BorderLayout());
        JPanel pnlNorth = new JPanel();
        JPanel pnlWest = new JPanel();
        JPanel pnlSouth = new JPanel();
        JPanel pnlEast = new JPanel();

        JPanel pnlNorthW = new JPanel();
        JPanel pnlNorthE = new JPanel();
        JPanel pnlCenterS = new JPanel();
        pnlCenterCard = new JPanel();
        JPanel pnlCenter = new JPanel();
        JPanel pnlCenterInfo = new JPanel();

        pnlNorth.setLayout(new BorderLayout());
        pnlWest.setLayout(new FlowLayout());
        pnlSouth.setLayout(new BorderLayout());
        pnlEast.setLayout(new FlowLayout());
        pnlCenterS.setLayout(new FlowLayout());
        pnlCenterCard.setLayout(new FlowLayout());
        pnlCenter.setLayout(new BoxLayout(pnlCenter, BoxLayout.Y_AXIS));
        pnlCenterInfo.setLayout(new FlowLayout());

        pnlNorthW.setLayout(new BorderLayout());
        pnlNorthE.setLayout(new BorderLayout());


        pnlNorthW.setPreferredSize(new Dimension(300, 200));
        pnlNorthE.setPreferredSize(new Dimension(300, 200));

        for(Player i : tabel)
            i.addMouseListener(new PlayerLyss());

        pnlNorthW.add(tabel[0], BorderLayout.WEST);
        pnlNorthW.add(tabel[1], BorderLayout.EAST);

        pnlNorthE.add(tabel[2], BorderLayout.EAST);
        pnlNorthE.add(tabel[3], BorderLayout.WEST);

        pnlNorth.add(pnlNorthW, BorderLayout.WEST);
        pnlNorth.add(pnlNorthE, BorderLayout.EAST);

        pnlWest.add(tabel[4]);
        pnlSouth.add(tabel[5], BorderLayout.WEST);
        pnlSouth.add(tabel[6], BorderLayout.EAST);
        pnlEast.add(tabel[7]);

        add(pnlNorth, BorderLayout.NORTH);
        pnlSouth.add(pnlCenterS, BorderLayout.CENTER);
        add(pnlWest, BorderLayout.WEST);
        add(pnlSouth, BorderLayout.SOUTH);
        add(pnlEast, BorderLayout.EAST);
        add(pnlCenter, BorderLayout.CENTER);
        pnlCenter.add(pnlCenterCard);
        pnlCenter.add(pnlCenterInfo);

        JButton btnBet = new JButton("Bet/Raise");
        btnBet.addActionListener(new BetLyss());
        txtBet = new JFormattedTextField(NumberFormat.getInstance());
        txtBet.setColumns(4);
        txtBet.setText("100");
        pnlCenterS.add(btnBet);
        pnlCenterS.add(txtBet);
        JButton btnFold = new JButton("Fold");
        btnFold.addActionListener(new FoldLyss());
        pnlCenterS.add(btnFold);
        JButton btnCheck = new JButton("Check/Call");
        btnCheck.addActionListener(new CheckLyss());
        pnlCenterS.add(btnCheck);

        JButton btnAllin = new JButton("All in");
        btnAllin.addActionListener(new AllinLyss());
        pnlCenterS.add(btnAllin);

        txtLog = new JTextArea("", 6, 25);
        txtLog.setEditable(false);
        pnlCenterInfo.add(new JScrollPane(txtLog));


        JMenuBar mbar = new JMenuBar();
        setJMenuBar(mbar);
        JMenu fileMenu = new JMenu("File");
        mbar.add(fileMenu);
        JMenuItem startItem = new JMenuItem("Start");
        fileMenu.add(startItem);
        startItem.addActionListener(new StartLyss());
        JMenuItem quitItem = new JMenuItem("Quit");
        fileMenu.add(quitItem);
        quitItem.addActionListener(new QuitLyss());

        setSize(1000, 650);
        setVisible(true);
        setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);

        WindowListener windowListener = new WindowAdapter()
        {
            @Override
            public void windowClosing (WindowEvent e)
            {
                try
                {
                    client.quit();
                    System.out.println("Closeing");
                    System.exit(0);
                }
                catch (IOException ex)
                {
                    Logger.getLogger(PokerGUI.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        };

        addWindowListener(windowListener);
    }

    public static void main(String[] args) throws IOException
    {

        StartForm frm = new StartForm();

        //Dont do any value controll.
        showConfirmDialog(null, frm, "Start Info",
                            DEFAULT_OPTION);

        PokerGUI m = new PokerGUI();

       client = new Client(m);
       client.initConnection(frm.getIP(), 3333);
       client.letMeJoin(frm.getName(), frm.getMoney());
    }

    public void bet(Integer playerID, Integer amount)
    {
        txtLog.append(tabel[playerID].getName()+ " bet " + String.valueOf(amount) + "\r\n");
    }

    public void raise(Integer playerID, Integer amount)
    {
        txtLog.append(tabel[playerID].getName()+ " raise" + amount + "\r\n");
    }

    public void fold(Integer playerID)
    {
         txtLog.append(tabel[playerID].getName()+ " fold\r\n");
    }

    public void check(Integer playerID)
    {
        txtLog.append(tabel[playerID].getName()+ " check\r\n");
    }

    public void inactive(Integer playerID)
    {
        txtLog.append(tabel[playerID].getName()+ " inactive\r\n");
    }

    public void phaseChange(Integer newPhase)
    {
       txtLog.append("Phase change" + newPhase + "\r\n");
    }

    public void showDown() {
        txtLog.append("Show down\r\n");
    }

    public void splitPot() {
        txtLog.append("Split pot\r\n");
    }

    public void dealTableCard(holdem.Card newTableCard)
    {
        pnlCenterCard.add(new MyCard(newTableCard));
        pnlCenterCard.repaint();
        pnlCenterCard.revalidate();
        txtLog.append("New table card\r\n");
    }

    public void moneyGain(Integer playerID, Integer amount)
    {
        tabel[playerID].setMoney(tabel[playerID].getMoney() + amount);
        txtLog.append("Money Gain: " + tabel[playerID].getName() + amount + "\r\n");
    }

    public void changeTurn(Integer playerID)
    {
        txtLog.append("Turn: " + tabel[playerID].getName()+ "\r\n");
        turn = playerID;
    }

    public void revealPlayerHand(Map<Integer, java.util.List<Card>> cardMap)
    {
        Iterator it = cardMap.entrySet().iterator();
        while (it.hasNext())
        {
            Map.Entry<Integer, java.util.List<Card>> pairs = (Map.Entry)it.next();

            MyCard tmp[] = new MyCard[2];
            tmp[0] = new MyCard(pairs.getValue().get(0));
            tmp[1] = new MyCard(pairs.getValue().get(1));

            tabel[pairs.getKey()].setHand(tmp);
        }
    }

    public void gameStart()
    {
        pnlCenterCard.removeAll();
        pnlCenterCard.setLayout(new FlowLayout());
        for(Player i : tabel)
            i.setHand(new MyCard[2]);
        txtLog.append("Start game\r\n");
    }

    public void gameEnd()
    {
        txtLog.append("Game end\r\n");
    }

    public void smallBlindIncrease(Integer playerID, Integer newAmount)
    {
        txtLog.append(tabel[playerID].getName() + " Small blind\r\n");
    }

    public void bigBlindIncrease(Integer playerID, Integer newAmount)
    {
        txtLog.append(tabel[playerID].getName() + " Big blind\r\n");
    }

    public void dealHandCard(Card handCards[])
    {
        MyCard tmp[] = new MyCard[2];
        tmp[0] = new MyCard(handCards[0]);
        tmp[1] = new MyCard(handCards[1]);

        tabel[me].setHand(tmp);
        System.out.println(tabel[me].getHand()[0].picSource());
        System.out.println(tabel[me].getHand()[1].picSource());
    }

    public void newPlayer(Integer playerID, String playerName, Integer money)
    {
        tabel[playerID].joinGame(playerName, money);
        txtLog.append(playerName+ " join the game\r\n");
    }

    public void joinAccpted(Integer playerID)
    {
        me = playerID;
        tabel[me].setMe(true);
        txtLog.append("Join accepted\r\n");
    }

    public void dealerChange(Integer playerID)
    {
        txtLog.append(tabel[playerID].getName() + " is dealer\r\n");
    }

    public void quit(Integer playerID)
    {
        txtLog.append(tabel[playerID].getName() + " has quit\r\n");
    }

    class PlayerLyss extends MouseAdapter
    {
        @Override
        public void mouseClicked(MouseEvent e)
        {
            Player tmp =((Player)e.getSource());

            if(!playing && !tmp.isActive())
            {
                playing = !playing;
                //tmp.joinGame("arne", 32, 4);
            }
        }
    }

    class QuitLyss implements ActionListener
    {
	public void actionPerformed(ActionEvent ave)
        {
            try
            {
                client.quit();
            }
            catch (IOException ex)
            {
                Logger.getLogger(PokerGUI.class.getName()).log(Level.SEVERE, null, ex);
            }
            System.exit(0);
	}
    }

    class BetLyss implements ActionListener
    {
	public void actionPerformed(ActionEvent ave)
        {
            try
            {
                client.bet(Integer.parseInt( txtBet.getText()));
            }
            catch (IOException ex)
            {
                System.out.println(ex.getMessage());
            }
	}
    }

    class CheckLyss implements ActionListener
    {
	public void actionPerformed(ActionEvent ave)
        {
            try
            {
                client.check();
            }
            catch (IOException ex)
            {
                System.out.println(ex.getMessage());
            }
	}
    }

    class AllinLyss implements ActionListener
    {
	public void actionPerformed(ActionEvent ave)
        {
            try
            {
                client.bet(tabel[me].getMoney());
            }
            catch (IOException ex)
            {
                System.out.println(ex.getMessage());
            }
	}
    }

    class FoldLyss implements ActionListener
    {
	public void actionPerformed(ActionEvent ave)
        {
            try
            {
                client.fold();
            }
            catch (IOException ex)
            {
                System.out.println(ex.getMessage());
            }
	}
    }

    class StartLyss implements ActionListener
    {
	public void actionPerformed(ActionEvent ave)
        {
            try
            {
                client.start();
            }
            catch (IOException ex)
            {
                System.out.println(ex.getMessage());
            }
	}
    }
}